#include "stm32f10x.h"                  // Device header

uint16_t AD_Value[4];
//寻址空间是32位的进行映射，但是ADC的数据寄存器是16位的

void AD_Init(void)
{
	//1.开启RCC时钟，包括ADC和GPIO和DMA的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2ENR_ADC1EN,ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	//配置ADCCLK分频器
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//=12MHz
	//2.配置GPIO输入模式
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//3.配置模拟开关，选择规则组的输入通道
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//采样时间等于55.5个周期,+固定的12.5个ADC周期 = 68个周期;
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
	
	//4.配置ADC转换器：包括ADC是单次转换还是连续转换，扫描还是非扫描、有几个通道；触发源是什么，数据对齐是左对济还是右对齐
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//DISABLE单次转换,ENABLE:连续转换
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描
	ADC_InitStructure.ADC_NbrOfChannel = 4;//仅在扫描模式下才需要这个参数
	ADC_Init(ADC1,&ADC_InitStructure);
	

	//调用DMA初始化函数
	/*外设站点的起始地址、数据宽度、是否自增*/
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//ADC_DR的地址0x4001244c
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//以半字16位转运
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//不自增
	/*存储器站点的起始地址、数据宽度、是否自增*/
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器的地址是自增的，每转运一次挪1位
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//传输方向
	DMA_InitStructure.DMA_BufferSize = 4;//缓存区大小，传输计数器
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA循环模式
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//传输模式，是否使用自动重装 DMA_M2M_Disable:使用硬件触发
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//优先级
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
	/*如果选择硬件触发：调用xxx_DMACmd,开启触发信号输出 DMA中断：DMA_ITConfig开启中断输出：再在NVIC里，配置相应的中断通道，然后写中断函数就行了*/
	DMA_Cmd(DMA1_Channel1,ENABLE);
	ADC_DMACmd(ADC1,ENABLE);//开启DMA触发信号
	
	//5.开关控制，调用一下ADC_Cmd函数，开启ADC
	ADC_Cmd(ADC1,ENABLE);
	//6.校准
	ADC_ResetCalibration(ADC1);//返回复位校准状态
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//返回复位校准状态
	ADC_StartCalibration(ADC1);//开始校准
	while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//ADC连续转换，DMA循环转运
}

//void AD_GetValue(void)
//{
//	DMA_Cmd(DMA1_Channel1,DISABLE);
//	DMA_SetCurrDataCounter(DMA1_Channel1,4);
//	DMA_Cmd(DMA1_Channel1,ENABLE);
//	

//	
//	while(DMA_GetFlagStatus(DMA1_FLAG_GL1) == RESET);//转运完成后，标志位置1
//	DMA_ClearFlag(DMA1_FLAG_GL1);//清除标志位

//}
